package com.begye.smartloan.apptest.tool

import android.content.Intent
import android.os.Handler
import android.os.Looper
import androidx.lifecycle.MutableLiveData
import com.begye.smartloan.apptest.MyApplication
import com.begye.smartloan.apptest.ext.toFullUrl
import com.begye.smartloan.apptest.signinup.ui.SignInUpActivity
import com.data.analysislib.AnalyticsUtil
import com.data.datalib.util.addPathSeparator
import com.data.datalib.util.removePathSeparator
import com.google.gson.Gson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.ConnectionPool
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.json.JSONObject
import java.io.File
import java.io.IOException
import java.util.TimeZone
import java.util.concurrent.TimeUnit

fun HashMap<String, Any>.createApiAction(): HashMap<String, Any> {
    apply {
        put("token", LoginTool.filterSession())
        put("userId", LoginTool.filterUID())
        put("version", MyApplication.appVersion.toString())
        put("product", MyApplication.product)
        put("channelCode", AnalyticsUtil.getInstallReferrer())
        put("subChannelCode", AnalyticsUtil.getInstallReferrer())
        put("clientType", "ANDROID")
        put("apiVersion", "v3")
        put("androidId", AnalyticsUtil.getAndroidId())
        put("advertId", AnalyticsUtil.getAdId())
    }
    return this
}

fun HashMap<String, Any>.toRequestBody(): RequestBody {
    val content = Gson().toJson(this).trim()
    println("aes before：\n $content")

    val encrypted: String = AesTool.encryptDefault(content)
    println("aes after：\n $encrypted")

    val mediaType = "text/plain".toMediaTypeOrNull()
    return encrypted.toRequestBody(mediaType)
}

fun HashMap<String, Any>.toRequestZoneBody(): RequestBody {
    val content = Gson().toJson(this).trim()
    println("aes before：\n $content")

    val encrypted: String = AesTool.encryptDefault(content)
    println("aes after：\n $encrypted")

    val mediaType = "text/plain".toMediaTypeOrNull()
    return encrypted.toRequestBody(mediaType)
}

const val apiHost = "http://159.138.165.72"
private const val apiZonePath = "/beg738ydfaedkslf438734sika"
private const val apiBusinessPath = "/lqc6UPVXXsBuXOfffFUyJw"
private const val apiUploadFilePath = "/v4aMwxMTM0CzZS37Tx1J0uA"

private fun apiHostZoneCombine(): String {
    return "$apiHost$apiZonePath"
}

private fun apiHostUploadFileCombine(): String {
    return "$apiHost${MyApplication.pServer.addPathSeparator()}$apiUploadFilePath"
}

private val apiClient = OkHttpClient.Builder()
    .connectTimeout(60, TimeUnit.SECONDS)
    .writeTimeout(60, TimeUnit.SECONDS)
    .readTimeout(60, TimeUnit.SECONDS)
    .retryOnConnectionFailure(true)
    .connectionPool(ConnectionPool(5, 3, TimeUnit.MINUTES))
    .protocols(listOf(Protocol.HTTP_1_1))
    .addNetworkInterceptor(printInterceptor)
    .sslSocketFactory(SSLTool.createSSLSocketFactory()!!, SSLTool.TrustAllCerts())
    .hostnameVerifier(SSLTool.TrustAllHostnameVerifier())
    .build()

val mainHandlerApp = Handler(Looper.getMainLooper())

interface IApiProcessCallback {
    fun onApiReady()
    fun onApiDone(jsonObject: JSONObject)
    fun onApiError(code: String, errMsg: String)
}

//private fun reqMimeType(fileName: String): String {
//    return URLConnection.guessContentTypeFromName(fileName) ?: "application/octet-stream"
//}

fun doPostRequest(
    path: String,
    action: HashMap<String, Any>,
    loading: MutableLiveData<Boolean>? = null,
    callback: IApiProcessCallback?
) {

    // 状态回调
    callback?.onApiReady()

    // loading start
    loading?.let { ding ->
        if (ding.value != true) {
            ding.value = true
        }
    }

    // 组装body
    val body: RequestBody =
        action.apply { put("path", path.removePathSeparator()) }.createApiAction().toRequestBody()

    // 目标地址
    val url = apiBusinessPath.toFullUrl()

    // 构建POST请求
    val request = Request.Builder()
        .url(url)
        .post(body)
        .addHeader("Content-Type", "text/plain")
        .addHeader("Accept", "*/*")
        .addHeader("product", MyApplication.product.uppercase())
        .build()

    apiClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            mainHandlerApp.post {
                loading?.value = false
                callback?.onApiError("9191", e.localizedMessage ?: "Request Error")
            }
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                if (!it.isSuccessful) {
//                    println("Response: ${response.code}-${response.message}")
                    mainHandlerApp.post {
                        loading?.value = false
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return
                }

                val responseData = response.body?.string()
                if (responseData == null) {
                    mainHandlerApp.post {
                        loading?.value = false
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return@use
                }

                try {
                    val resJsonString = AesTool.decryptDefault(responseData)
                    HttpLogInterceptor.printJson(resJsonString)

                    val resJsonObject = JSONObject(resJsonString)
                    val resCode = resJsonObject.optString("code", "-1").toInt()
                    val resMsg = resJsonObject.optString("msg")
                    if (resCode == 0) {
                        mainHandlerApp.post {
                            loading?.value = false
                            callback?.onApiDone(resJsonObject)
                        }
                    } else {
                        mainHandlerApp.post {
                            loading?.value = false
                            callback?.onApiError("$resCode", resMsg)
                            ToastTool.showMsg(resMsg)
                            if (resMsg.contains("User does not exist", true)) {
                                MyApplication.context.startActivity(
                                    Intent(
                                        MyApplication.context,
                                        SignInUpActivity::class.java
                                    ).apply {
                                        addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
                                    })
                            }
                        }
                    }
                } catch (e: Exception) {
//                    e.printStackTrace()
                    mainHandlerApp.post {
                        loading?.value = false
                        val resMsg = e.localizedMessage ?: "Request Error"
                        callback?.onApiError("-2", resMsg)
                        ToastTool.showMsg(resMsg)
                    }
                }
            }
        }
    })
}

fun doZoneRequest(callback: IApiProcessCallback?) {
    callback?.onApiReady()

    val url = apiHostZoneCombine()
    val body = hashMapOf<String, Any>().apply {
        put("tz", TimeZone.getDefault().id.toString())
        put("p", MyApplication.product.lowercase())
    }.toRequestZoneBody()

    val request = Request.Builder()
        .url(url)
        .post(body)
        .addHeader("Content-Type", "text/plain")
        .addHeader("Accept", "*/*")
        .addHeader("product", MyApplication.product)
        .build()

    apiClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            mainHandlerApp.post {
                callback?.onApiError("9191", e.localizedMessage ?: "Request Error")
            }
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                if (!it.isSuccessful) {
                    println("Response: ${response.code}-${response.message}")
                    mainHandlerApp.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return
                }

                val responseData = response.body?.string()
                if (responseData == null) {
                    mainHandlerApp.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return@use
                }

                try {
                    val resJsonString = AesTool.decryptDefault(responseData)
                    val resJsonObject = JSONObject(resJsonString)
                    val resCode = resJsonObject.optString("code", "-1").toInt()
                    val resMsg = resJsonObject.optString("msg")
                    if (resCode == 0) {
                        mainHandlerApp.post {
                            callback?.onApiDone(resJsonObject)
                        }
                    } else {
                        mainHandlerApp.post {
                            callback?.onApiError("$resCode", resMsg)
                            ToastTool.showMsg(resMsg)
                        }
                    }
                } catch (e: Exception) {
//                    e.printStackTrace()
                    mainHandlerApp.post {
                        callback?.onApiError("-2", e.localizedMessage ?: "Request Error")
                    }
                }
            }
        }
    })
}

fun doImageUpload(
    filePath: String,
    loading: MutableLiveData<Boolean>? = null,
    callback: IApiProcessCallback?
) {
    callback?.onApiReady()
    // loading start
    loading?.let { ding ->
        if (ding.value != true) {
            ding.value = true
        }
    }

    try {
        val file = File(filePath)
        val mediaType = if (filePath.endsWith(".png")) "image/png" else "image/jpg"
        val requestBody = file.asRequestBody(mediaType.toMediaTypeOrNull())

        val body = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("image", file.name, requestBody)
            .build()

        val url = apiHostUploadFileCombine()

        val request = Request.Builder()
            .url(url)
            .post(body)
            .addHeader("Accept", "*/*")
            .addHeader("product", MyApplication.product)
            .build()

        apiClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                mainHandlerApp.post {
                    loading?.value = false
                    callback?.onApiError("9191", e.localizedMessage ?: "Request Error")
                }
            }

            override fun onResponse(call: Call, response: Response) {
                response.use {
                    if (!it.isSuccessful) {
                        mainHandlerApp.post {
                            loading?.value = false
                            callback?.onApiError("${response.code}", response.message)
                        }
                        return
                    }

                    val responseData = response.body?.string()
                    if (responseData == null) {
                        mainHandlerApp.post {
                            loading?.value = false
                            callback?.onApiError("${response.code}", response.message)
                        }
                        return
                    }

                    val resJsonObject = JSONObject(responseData)
                    val resCode = resJsonObject.optString("code", "-1").toInt()
                    val resMsg = resJsonObject.optString("msg")
                    if (resCode == 0) {
                        mainHandlerApp.post {
                            loading?.value = false
                            val obj = resJsonObject.optJSONObject("obj") ?: JSONObject()
                            callback?.onApiDone(obj)
                        }
                    } else {
                        mainHandlerApp.post {
                            loading?.value = false
                            callback?.onApiError("$resCode", resMsg)
                            ToastTool.showMsg(resMsg)
                        }
                    }
                }
            }
        })
    } catch (e: Exception) {
        mainHandlerApp.post {
            loading?.value = false
            val resMsg = e.localizedMessage ?: "Request Error"
            callback?.onApiError("-2", resMsg)
            ToastTool.showMsg(resMsg)
        }
    }
}

fun addTouch(
    type: String,
    remark: String = "",
    isOpen: Boolean = false,
    isComplete: Boolean = false
) {
    try {
        val startPrefix = MyApplication.product + "_"
        var typeFormat = if (type.startsWith(startPrefix, true)) {
            type
        } else {
            startPrefix + type
        }
        if (isOpen) {
            typeFormat += "_START"
        } else if (isComplete) {
            typeFormat += "_END"
        }
        typeFormat = typeFormat.uppercase()

        val params = hashMapOf<String, Any>()
        params["type"] = typeFormat
        params["remark"] = remark

        doPostRequest("ORWCJzopV22qgfIqJAWGQ", params, null, object : IApiProcessCallback {
            override fun onApiReady() {
            }

            override fun onApiDone(jsonObject: JSONObject) {
            }

            override fun onApiError(code: String, errMsg: String) {
            }
        })

    } catch (e: Exception) {
        //
    }
}
